package com.construction.api.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.construction.api.config.annotation.ValidToken;
import com.construction.api.domain.entity.SysUser;
import com.construction.api.domain.model.header.Header;
import com.construction.api.domain.model.token.Payload;
import com.construction.api.domain.model.token.User;
import com.construction.api.domain.vo.TokenVO;
import com.construction.api.enums.RoleEnum;
import com.construction.api.service.TokenService;
import com.construction.api.util.JwtTokenUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.method.HandlerMethod;

/**
 * @author dybin
 * @Date: 2021/7/2 21:50
 */
@Service
@RequiredArgsConstructor
public class TokenServiceImpl implements TokenService<Payload> {

    private final JwtTokenUtil jwtTokenUtil;

    @Override
    public boolean verifyToken(Header header) {
        return jwtTokenUtil.verifyToken(header.getToken());
    }

    @Override
    public Payload resolvToken(Header header) {
        return jwtTokenUtil.resolvToken(header.getToken());
    }

    @Override
    public TokenVO allocateToken(SysUser sysUser) {
        User user = BeanUtil.copyProperties(sysUser, User.class);
        Payload payload = new Payload();
        payload.setProjectId(sysUser.getProjectId());
        payload.setRole(RoleEnum.of(Integer.valueOf(sysUser.getRoleIds())));
        payload.setUser(user);
        String accessToken = jwtTokenUtil.createDesToken(payload);
        return TokenVO.builder()
                .accessToken(accessToken)
                .expireIn(payload.getExp()).build();
    }

    @Override
    public boolean isSkip(Object handler) {
        if (handler instanceof HandlerMethod) {
            return !((HandlerMethod) handler).getBeanType().isAnnotationPresent(ValidToken.class);
        }
        return true;
    }

    @Override
    public TokenVO refreshToken(String token) {
        String accessToken = jwtTokenUtil.refreshToken(token);
        Payload payload = jwtTokenUtil.resolvToken(accessToken);
        String desToken = jwtTokenUtil.encrypt(accessToken);
        return TokenVO.builder()
                .accessToken(desToken)
                .expireIn(payload.getExp()).build();
    }
}
